/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: Interrupt
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2021-12-03     JasonHu           Init
 */

#define __ASSEMBLY__
#include <context.h>
#include <regs.h>
#include <base/defines.h>

.text

.extern TrapDispatch
.extern TrapSwitchStack
.extern NX_IRQ_OverCheck

.extern gStackTop0
.extern gStackTop1
.extern gStackTop2
.extern gStackTop3
.extern gStackTop4

.globl gTrapEntry0
.globl gTrapEntry1
.globl gTrapEntry2
.globl gTrapEntry3
.globl gTrapEntry4

.align 2 # TrapEntry must aligin with 4 byte
NX_FUNC(gTrapEntry0)
    /* save sp to sscratch reg, sscratch saved old sp from user/kernel */
    csrrw sp, sscratch, sp    
    /* switch to cpu stack as temp stack */
    la sp, gStackTop0
    j TrapEntry

.align 2
NX_FUNC(gTrapEntry1)
    csrrw sp, sscratch, sp    
    la sp, gStackTop1
    j TrapEntry

.align 2
NX_FUNC(gTrapEntry2)
    csrrw sp, sscratch, sp    
    la sp, gStackTop2
    j TrapEntry

.align 2
NX_FUNC(gTrapEntry3)
    csrrw sp, sscratch, sp    
    la sp, gStackTop3
    j TrapEntry

.align 2
NX_FUNC(gTrapEntry4)
    csrrw sp, sscratch, sp    
    la sp, gStackTop4
    j TrapEntry

NX_FUNC(TrapEntry)

    /* save context to cpu stack */
    SAVE_CONTEXT

    /* switch stack from CPU stack to thread stack */
    mv a0, sp
    call TrapSwitchStack
    mv sp, a0 /* a0 saved new stack */

    /* call handler */
    mv a0, sp
    call TrapDispatch

    /* irq over check */
    mv a0, sp /* sp arg */
    call NX_IRQ_OverCheck
    mv a0, sp /* sp arg */
    call TrapSignalCheck
    mv a0, sp /* sp arg */
    call NX_IRQ_OverCheck2

    tail TrapReturn

NX_FUNC(TrapReturn)
    /* restore context will restore sp */
    RESTORE_CONTEXT
    /* return from supervisor call */
    sret
NX_ENDFUNC(TrapEntry)
